#include "task_manage.h"

// 全局变量定义
g_param_t g_param;
g_cfg_t *g_cfg = NULL;

const api_t core_api = {
    core_msg_handler,   // 消息路由处理函数
    log_print           // 日志打印
};


/**
 * Name:    g_cfg_init
 * Brief:   全局配置初始化
 * Input:   NULL
 * Output:  NULL
 */
static void g_cfg_init(void)
{
    g_cfg = (g_cfg_t *)malloc(sizeof(g_cfg_t));

    g_cfg->g_basic = NULL;      // 基础配置
    g_cfg->g_template = NULL;   // 模板库
    g_cfg->g_coll_link = NULL;  // 采集通道
    g_cfg->g_trans_link = NULL; // 转发通道
}

int par_config_init()
{
    g_cfg_init();

    // SYS.json文件
    char *cfg_buff_sys = (char *)util_file_read(GW_CFG_SYS);
    if (cfg_buff_sys == NULL)
    {
        LOG_E("cfg", "Failed to READ SYS.json!\n");
        return -1;
    }
    // CLT.json文件
    char *cfg_buff_clt = (char *)util_file_read(GW_CFG_CLT);
    if (cfg_buff_clt == NULL)
    {
        LOG_E("cfg", "Failed to READ CLT.json!\n");
        return -1;
    }

    // 获取SYS.json的根节点
    cJSON *root_sys = cfg_create_root(cfg_buff_sys);
    if (root_sys == NULL)
    {
        LOG_E("cfg", "Failed to Parse SYS.json!\n");
        if (cfg_buff_sys)
            free(cfg_buff_sys);
        return -1;
    }
    free(cfg_buff_sys);

    // 获取CLT.json的根节点
    cJSON *root_clt = cfg_create_root(cfg_buff_clt);
    if (root_clt == NULL)
    {
        LOG_E("cfg", "Failed to Parse CLT.json!\n");
        if (cfg_buff_clt)
            free(cfg_buff_clt);
        return -1;
    }
    free(cfg_buff_clt);

    LOG_D("main", "Param_config_init...Start");

    // 获取基础配置
    g_cfg->g_basic = cfg_create_basic(root_sys);
    if (g_cfg->g_basic == NULL)
    {
        if (root_sys)
            cJSON_Delete(root_sys);
        return -1;
    }

    // 获取采集通道
    g_cfg->g_coll_link = cfg_create_coll_node(root_sys, root_clt);

    // 获取转发节点
    g_cfg->g_trans_link = cfg_create_trans_node(root_sys, root_clt);

    // RULE.json文件
    char *cfg_buff_rule = (char *)util_file_read(GW_CFG_RULE);
    if (cfg_buff_rule == NULL)
    {
        LOG_E("cfg", "Failed to READ RULE.json!\n");
        return -1;
    }
    // 获取RULE.json的根节点
    cJSON *root_rule = cfg_create_root(cfg_buff_rule);
    if (root_rule == NULL)
    {
        LOG_E("cfg", "Failed to Parse RULE.json!\n");
        if (cfg_buff_rule)
            free(cfg_buff_rule);
        return -1;
    }
    free(cfg_buff_rule);

    // cfg_create_alarm(root_rule);

    if (root_rule)
        cJSON_Delete(root_rule);
    if (root_sys)
        cJSON_Delete(root_sys);
    if (root_clt)
        cJSON_Delete(root_clt);


    // RULE.json
    // ALM_YC
    // ALM_YX


    LOG_D("main", "Param_config_init...Done\n");

    return 0;
}

/**
 * Name:    protocol_init
 * Brief:   规约加载
 * Input:   NULL
 * Output:  0--成功，-1--失败
 */
int protocol_init(void)
{
    LOG_I("main", "protocol_init...Start");

    // 南向规约回调函数加载到采集节点
    {
        cfg_pu_t *pu = g_cfg->g_coll_link;
        while (pu)
        {
            dlmodule_t *dlmodule = NULL;

            if (0 == strcmp(pu->protoname, "ModbusHost_RTU_Addr"))
            {
                dlmodule = (dlmodule_t *)malloc(sizeof(dlmodule_t));
                dlmodule->init = ModbusHost_RTU_Addr.init;
                dlmodule->run = ModbusHost_RTU_Addr.run;
                dlmodule->msg = ModbusHost_RTU_Addr.msg;
            }

            if(NULL == dlmodule)
            {
                LOG_E("dlmodule", "failed to load coll protocol: %s function",pu->protoname);
            }

            pu->hanlder.dlmodule = (void *)dlmodule;
            pu->hanlder.api = (void *)&core_api;
            pu = pu->next;
        }
    }

    // 北向规约回调函数加载到采转发节点
    {
        cfg_pu_t *pu = g_cfg->g_trans_link;
        while (pu)
        {
            dlmodule_t *dlmodule = NULL;

            if (0 == strcmp(pu->protoname, "Acrel_EIot"))
            {
                dlmodule = (dlmodule_t *)malloc(sizeof(dlmodule_t));
                dlmodule->init = EIOT.init;
                dlmodule->run = EIOT.run;
                dlmodule->msg = EIOT.msg;
            }
            else if (0 == strcmp(pu->protoname, "AWT-IOT"))
            {
                dlmodule = (dlmodule_t *)malloc(sizeof(dlmodule_t));
                dlmodule->init = AWTIOT.init;
                dlmodule->run = AWTIOT.run;
                dlmodule->msg = AWTIOT.msg;
            }

            if(NULL == dlmodule)
            {
                LOG_E("dlmodule", "failed to load trans protocol: %s function",pu->protoname);
            }

            pu->hanlder.dlmodule = (void *)dlmodule;
            pu->hanlder.api = (void *)&core_api;
            pu = pu->next;
        }
    }
    LOG_I("main", "protocol_init...Done\n");
    return 0;
}

/**
 * Name:    task_manage
 * Brief:   动态库、主程序运行
 * Input:   NULL
 * Output:  0--成功，-x--失败
 */
int task_manage()
{
    LOG_I("main", "init");

    // 初始化南向节点
    {
        cfg_pu_t *pu = g_cfg->g_coll_link;
        while (pu)
        {
            pu->enable = 1;

            dlmodule_t *dlmodule = (dlmodule_t *)pu->hanlder.dlmodule;
            if (NULL == dlmodule)
            {
                LOG_E("core", "collect_init portname %s dlmodule is NULL", pu->name);
                pu = pu->next;
                continue;
            }

            if (0 != dlmodule->init(pu))
            {
                pu->enable = 0;
                LOG_W("main", "coll node:%s init error", pu->name);
            }
            pu = pu->next;
        }
    }

    // 初始化转发节点
    {
        cfg_pu_t *pu = g_cfg->g_trans_link;
        while (pu)
        {
            if (0 == pu->enable)
            {
                pu = pu->next;
                continue;
            }

            dlmodule_t *dlmodule = (dlmodule_t *)pu->hanlder.dlmodule;
            if (NULL == dlmodule)
            {
                LOG_E("core", "trans_init portname %s dlmodule is NULL", pu->name);
                pu = pu->next;
                continue;
            }

            if (0 != dlmodule->init(pu))
            {
                pu->enable = 0;
                LOG_W("main", "trans node:%s init error", pu->name);
            }
            pu = pu->next;
        }
    }

    // 创建南向节点线程
    {
        cfg_pu_t *pu = g_cfg->g_coll_link;
        while (pu)
        {
            if (0 == pu->enable)
            {
                pu = pu->next;
                continue;
            }

            pthread_t thread_coll;
            pthread_create(&thread_coll, NULL, coll_run, pu);
            pthread_detach(thread_coll);

            pu = pu->next;
        }
    }

    // 创建转发节点线程
    {
        cfg_pu_t *pu = g_cfg->g_trans_link;
        while (pu)
        {
            if (pu->enable == 1)
            {
                pthread_t thread_trans;
                pthread_create(&thread_trans, NULL, trans_run, pu);
                pthread_detach(thread_trans);
            }

            pu = pu->next;
        }
    }
}